package com.ms.qw.infraestructura.persistence.support;


import com.google.common.collect.Lists;
import com.ms.qw.domain.Builder;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * User: aglwkrs
 * Date: 01/12/11
 */
public class Database {
    private EntityManagerFactory entityManagerFactory;
    List<Object> persistentObjects = new ArrayList<Object>();

    public Database(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    public void persist(final Builder entity) throws Exception {
        persist(entity.build());
    }

    public void persist(final Object entity) throws Exception {
        final EntityManager entityManager = entityManagerFactory.createEntityManager();
        JPATransactor jpaTransactor = new JPATransactor(entityManager);
        UnitOfWork unitOfWork = new UnitOfWork() {
            @Override
            public void work() throws Exception {
                entityManager.persist(entity);
                persistentObjects.add(entity);
            }
        };
        jpaTransactor.perform(unitOfWork);
    }

    public void cleanUp() throws Exception {
        final EntityManager entityManager = entityManagerFactory.createEntityManager();
        Set setItems = new LinkedHashSet(persistentObjects);
        persistentObjects.clear();
        persistentObjects.addAll(setItems);
        List<Object> reverseList = Lists.reverse(persistentObjects);
        for (final Object entity : reverseList) {
            JPATransactor jpaTransactor = new JPATransactor(entityManager);
            UnitOfWork unitOfWork = new UnitOfWork() {
                @Override
                public void work() throws Exception {
                    Object mergedEntity = entityManager.merge(entity);
                    entityManager.remove(mergedEntity);
                }
            };
            jpaTransactor.perform(unitOfWork);
        }

    }

    public void merge(final Object entity) throws Exception {
        final EntityManager entityManager = entityManagerFactory.createEntityManager();
        JPATransactor jpaTransactor = new JPATransactor(entityManager);
        UnitOfWork unitOfWork = new UnitOfWork() {
            @Override
            public void work() throws Exception {
                entityManager.merge(entity);
            }
        };
        jpaTransactor.perform(unitOfWork);
    }

    public void remove(final Object entity) throws Exception {
        final EntityManager entityManager = entityManagerFactory.createEntityManager();
        JPATransactor jpaTransactor = new JPATransactor(entityManager);
        UnitOfWork unitOfWork = new UnitOfWork() {
            @Override
            public void work() throws Exception {
                Object merged = entityManager.merge(entity);
                entityManager.remove(merged);
            }
        };
        jpaTransactor.perform(unitOfWork);
    }

}
